﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace MT4Trainer
{
    using Encog.ML.Data;
    using Encog.ML.Train;
    using Encog.Neural.Networks;
    using Encog.Neural.Pattern;

    [System.Runtime.InteropServices.GuidAttribute("BD65310E-B69B-406A-9FB5-B6E63338E2D1")]
    public partial class Form1 : Form
    {
        private static NLog.Logger mLogger;

        public Form1()
        {
            InitializeComponent();
        }

        public BasicNetwork CreatedNetwork { get; set; }

        public SVMPattern SVMNetwork { get; set; }

        public void ChangeToolStripTextLabel(string aMessage)
        {
            //SafeInvoker.SafeInvoke(this.toolStripStatusLabel1.,()=>this.ChangeToolStripTextLabel(aMessage));

            this.toolStripStatusLabel1.Text = aMessage;
        }

        /// <summary>
        ///  Adds point to the chart when the timer ticks.
        /// </summary>
        /// <param name="iteration"> The iteration. </param>
        /// <param name="doublevals"> The doublevals. </param>
        public void PointsAddage(int iteration, double doublevals)
        {
            if (this.chart1.InvokeRequired)
            {
                chart1.Series[0].Points.AddXY(iteration, doublevals);
                this.chart1.Invalidate(true);
                //this.ErrorChart.Invoke(d, new object[] { doublevals });
            }
            else
            {
                chart1.Series[0].Points.AddXY(iteration, doublevals);
                this.chart1.Invalidate(true);
            }
        }

        public void WriteMessage(string message)
        {
            var t = Task.Factory.StartNew(() => mLogger.Info(message));
        }

        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        private static void Main(string[] args)
        {
            Application.EnableVisualStyles();
            // Application.SetCompatibleTextRenderingDefault(true);

            //Lets parse arguments.

            Application.Run(new Form1());
        }

        //public Form1()
        //{
        //    this.baseCommandLine = opt;
        //    InitializeComponent();

        //    // in case we used command lines to set the file name, we can set the csv file directly.
        //    if (!string.IsNullOrEmpty(this.baseCommandLine.InputFile)) this.CSVFile = this.baseCommandLine.InputFile;

        //}

        #region fields

        private string CSVFile { get; set; }

        private double CurrentError { get; set; }

        private int currentIteration { get; set; }

        //private Options baseCommandLine { get; set; }
        private bool IsTraining { get; set; }

        private string Symbol { get; set; }

        #endregion fields

        /// <summary>
        ///  Event handler. Called by ChartTimer for tick events.
        /// </summary>
        /// <param name="sender"> Source of the event. </param>
        /// <param name="e"> Event information. </param>
        private void ChartTimer_Tick(object sender, EventArgs e)
        {
            if (IsTraining)
            {
                PointsAddage(currentIteration, CurrentError);
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            mLogger = NLog.LogManager.GetCurrentClassLogger();
            mLogger.Info("Starting to parse arguments...");
        }

        #region draw chart

        private Brush[] brushes = { Brushes.Red, Brushes.Green, Brushes.Blue };

        private void UpdatePlotArea(Graphics g, double error, int iteration, IMLTrain train, BasicNetwork network)
        {
            string banner = "Iteration={0}  Error={1:0.00}";

            Text = string.Format(banner, iteration, error);

            g.FillRectangle(Brushes.White, 0, 0, 400, 400);

            foreach (IMLDataSet c in train.Training)
            {
                network.DumpWeights();
            }
            //foreach (float[] point in network.Points2D())
            //{
            //    g.FillRectangle(brushes[(int)point[2]], point[0] * 395, point[1] * 395, 5, 5);

            //}

            //foreach (double line in network.Structure.Flat.Weights)
            //{
            //    double a = -line[0] / line[1];

            //    double c = -line[2] / line[1];

            //    Point left = new Point(0, (int)(c * 400));

            //    Point right = new Point(400, (int)((a + c) * 400));

            //    g.DrawLine(new Pen(Color.Gray), left, right);

            //}
        }

        #endregion draw chart

        private void NetworkLoaderButton_Click(object sender, EventArgs e)
        {
            using (NetworkCreator creat = new NetworkCreator())
            {
                if (creat.ShowDialog() == DialogResult.OK)
                    this.CreatedNetwork = creat.ChosenNetwork;
            }
        }

        private void OpenCSVFileButton_Click(object sender, EventArgs e)
        {
            using (var formDia = new OpenFileDialog())
            {
                if (formDia.ShowDialog() == DialogResult.OK)
                {
                    if (!formDia.FileName.EndsWith("csv"))
                    {
                        mLogger.Info("Your file doesn't end with CSV...normally MT4 files are CSV...hopefully  you know what you are doing....");
                    }
                    mLogger.Info("Got your CSV file...");
                    this.CSVFile = formDia.FileName;
                }
            }
        }

        private void ParseFileToDataSets_Click(object sender, EventArgs e)
        {
            //AnalystHelperForm frm = new AnalystHelperForm();
            //var t = Task.Factory.StartNew(() => frm != null ? frm.ShowDialog() : DialogResult.None);

            using (AnalystHelperForm frm = new AnalystHelperForm())
            {
                frm.ShowDialog();
            }

            //  load.Load(new TickerSymbol(Symbol,"MT4"), )
        }

        private void ScriptEditorButton_Click(object sender, EventArgs e)
        {
            using (var editor = new ScriptEditor())
            {
                editor.ShowDialog();
            }
        }

        /// <summary>
        ///  Event handler. Called by toolStripButton1 for click events.
        ///  Basically lets place a symbol in case its not in the file.
        /// </summary>
        /// <param name="sender"> Source of the event. </param>
        /// <param name="e"> Event information. </param>
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            mLogger.Info("Opening a symbol getter form..");
            //Lets make a symbol getter form...
            using (SymbolGetter frm = new SymbolGetter())
            {
                //If button ok.
                if (frm.DialogResult == DialogResult.OK)
                {
                    //Lets grab the symbol , and put it in our symbol string.
                    if (string.IsNullOrEmpty(frm.SymbolTextBox.Text))
                    {
                        this.Symbol = frm.SymbolTextBox.Text;
                        mLogger.Info("Got symbol from symbol getter form..." + Symbol);
                    }
                }
            }
        }

        private void TrainButton_Click(object sender, EventArgs e)
        {
            try
            {
                using (var net = new NetworkTrainer(mLogger))
                {
                    net.ShowDialog();
                }
            }
            catch (Exception ex)
            {
                mLogger.Error(ex);
            }
        }
    }
}